use serde::Deserialize;

#[derive(Deserialize)]
pub struct WebConfig {
    pub addr: String,
    pub static_dir: String,
    pub static_path: String,
}

#[derive(Deserialize)]
pub struct RedisConfig {
    pub dsn: String,
}

#[derive(Deserialize)]
pub struct SessionConfig {
    pub prefix: String,
    pub id_name: String,
    pub lifetime: usize,
}

#[derive(Deserialize)]
pub struct CacheConfig {
    pub prefix: String,
    pub lifetime: usize,
}

#[derive(Deserialize)]
pub struct UploadConfig {
    pub max_size: usize,
    pub allow_types: String,
    pub dir: String,
}

#[derive(Deserialize)]
pub struct Config {
    pub web: WebConfig,
    pub redis: RedisConfig,
    pub session: SessionConfig,
    pub cache: CacheConfig,
    pub upload: UploadConfig,
    pub pg: deadpool_postgres::Config,
}

impl Config {
    pub fn from_env() -> Result<Self, config::ConfigError> {
        let mut cfg = config::Config::new();
        cfg.merge(config::Environment::new())?;
        cfg.try_into()
    }
}

impl UploadConfig {
    pub fn allow_types(&self) -> Vec<String> {
        self.allow_types
            .split('|')
            .into_iter()
            .map(|t| t.trim().to_lowercase())
            .collect()
    }
    pub fn is_allowed_type(&self, ext_name: &str) -> bool {
        for ext in self.allow_types().iter() {
            if ext.trim().to_lowercase() == ext_name {
                return true;
            }
        }
        false
    }
}
